package com.example.Sao.Serivce;

import android.content.Context;
import android.os.Message;
import android.util.Log;

import com.example.Sao.Data.DepartmentList;
import com.example.Sao.MyBean.DeviceUpBean;
import com.example.Sao.MyBean.PCInfoBean;
import com.example.Sao.MyBean.TxBean;
import com.example.Sao.ObjectBox.DeviceEntity;
import com.example.Sao.ObjectBox.DeviceEntity_;
import com.example.Sao.Tools.DepartmentFileutil;
import com.example.Sao.Tools.DesCBCUtil;
import com.example.Sao.Tools.DesECBUtil;
import com.example.Sao.Tools.ObjectBoxHelper;
import com.google.gson.Gson;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.Scheduler;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;

/**
 * @ProjectName: scan
 * @Package: com.example.Sao.Serivce
 * @ClassName: TCPConnect
 * @Description: java类作用描述
 * @Author: 作者名
 * @CreateDate: 2020/4/29 22:40
 * @UpdateUser: 更新者：
 * @UpdateDate: 2020/4/29 22:40
 * @UpdateRemark: 更新说明：
 * @Version: 1.0
 * PC可以通过USB连接、ADB端口映射连接本服务器
 */
public class PConnectThread extends Thread{
    private PCService.MHandler mHandler;
    private Boolean isRun = false;
   private BufferedOutputStream out = null;
   private InputStream in = null;
    private  Context context;
    private static final String TAG = "PConnect";
    private ServerSocket mServerSocket;
    private Socket mClient;
    private Callback callback;
    private ObjectBoxHelper objectBoxHelper;

    public PConnectThread(ObjectBoxHelper objectBoxHelper,Callback callback, Context context, PCService.MHandler mHandler){
        this.mHandler = mHandler;
        this.callback = callback;
        this.context = context;
        this.objectBoxHelper =objectBoxHelper;
    }

    @Override
    public void run() {
        try {
            String ip = InetAddress.getLocalHost().getHostAddress();
            if (mServerSocket==null) {
                mServerSocket = new ServerSocket();
                mServerSocket.setReuseAddress(true);
                mServerSocket.bind(new InetSocketAddress(9000));
            }
        } catch (IOException e) {
            Log.d(TAG,"建立服务器异常：" + e.getMessage());
        }
        while(!isRun) {
            try {
                if (mServerSocket!=null) {
                    mClient = mServerSocket.accept();
                    Log.d(TAG, "建立连接");
//                MyToast.setToast(context,"建立连接");
//                MyToast.setToast(context,"建立链接：" + mClient.getInetAddress().toString() + ":" + mClient.getPort());
                    out = new BufferedOutputStream(mClient.getOutputStream());
                    in = mClient.getInputStream();
                    upCheckdata(objectBoxHelper,out)
                           .subscribe(new Consumer<String>() {
                        @Override
                        public void accept(String o) throws Exception {
                             if ("succes".equals(o)){
                                 Thread.sleep(200);
                                 upBoxdata(objectBoxHelper,out)
                                         .subscribe(new Consumer<String>() {
                                             @Override
                                             public void accept(String o) throws Exception {
                                                 if ("succes".equals(o)){
                                                     Message message  =new Message();
                                                     message.what=1;
                                                     mHandler.handleMessage(message);
                                                 }
                                             }
                                         });
                             }
                        }
                    });
                    receive(in);
                }else {
                    break;
                }
            } catch (IOException e) {
                Log.e(TAG, "run: ", e);
                callback.callbcak(e.getMessage());
            }
        }
    }

    public void close(){
        setIsRun(true);
    }
    public void setIsRun(boolean isRun){
        this.isRun = isRun;
    }

    private void send(OutputStream out, String msg) throws IOException {
        out.write(msg.getBytes("utf-8"));
    }
    private void send(OutputStream out, byte[] msg) throws IOException {
        Log.d(TAG,"发送数"+msg.length);
        out.write(msg);
    }

    private void receive(InputStream in) throws IOException {
        try {
//        ByteBuf buf = Unpooled.buffer();
            int mun=0;
            byte buffer[] =new byte[1024*64];
            int temp =  -1;
            ByteArrayOutputStream byteArrayOutputStream = null;
            while ((temp = in.read(buffer,0,buffer.length))!=-1){
                if (mun==0) {
                    Message message = new Message();
                    message.obj = "正在接受PC的盘点数据";
                    message.what = 3;
                    mHandler.handleMessage(message);
                }
                mun++;
                if (byteArrayOutputStream==null){
                    byteArrayOutputStream = new ByteArrayOutputStream();
                }
                byteArrayOutputStream.write(buffer,0,temp);
                Thread.sleep(600);
                if (in.available()<=0){
                    Log.d(TAG, "dest.length：" + byteArrayOutputStream.toByteArray().length);
//                    String r = DesECBUtil.decryptDES(buffer, "key_123_");
                    String r = DesCBCUtil.decryptDES(byteArrayOutputStream.toByteArray(),"key_123_");
//                    Log.d(TAG,"生成字符"+r);
                    if (r.charAt(0)=='{'&&r.charAt(r.length()-1)=='}'){
                        Log.d(TAG, "收到字符：" + r);
                        byteArrayOutputStream = null;
                    PCInfoBean infoBean = new Gson().fromJson(r, PCInfoBean.class);
                     objectBoxHelper.removeall();
                        int num=0;
                        String name = "";
                        DepartmentList departmentList = new DepartmentList();
                        List<String>beanList = new ArrayList<>();
                        List<DeviceEntity> deviceListBean = new ArrayList<>();
                        for (int i = 0; i < infoBean.getData().getCheck().size(); i++) {
                            PCInfoBean.DataBean.CheckBean checkBean = infoBean.getData().getCheck().get(i);
                            DeviceEntity entity = new DeviceEntity();
                            entity.setDeviceName(infoBean.getData().getCheck().get(i).getDeviceRealName());
                            entity.setDeviceStreamCode(infoBean.getData().getCheck().get(i).getDeviceStreamCode());
                            entity.setLocationFloor(infoBean.getData().getCheck().get(i).getLocationFloor());
                            entity.setLocationIbm(infoBean.getData().getCheck().get(i).getLocationIbm());
                            entity.setLocationPosition(infoBean.getData().getCheck().get(i).getLocationPosition());
                            entity.setLocationRoom(infoBean.getData().getCheck().get(i).getLocationRoom());
                            entity.setUseDepartment(infoBean.getData().getCheck().get(i).getUseDepartment());
                            entity.setStaus(false);
                            deviceListBean.add(entity);
                            if (i == 0) {
                                name = checkBean.getUseDepartment();
                                beanList.add(checkBean.getUseDepartment());
                            } else {
                                if (checkBean.getUseDepartment() != null && !name.equals(checkBean.getUseDepartment())) {
                                    int o = 0;
                                    for (int j = 0; j < beanList.size(); j++) {
                                        if (checkBean.getUseDepartment() != null && !beanList.get(j).equals(checkBean.getUseDepartment())) {
                                            o++;
                                        }
                                    }
                                    if (o == beanList.size()) {
                                        beanList.add(checkBean.getUseDepartment());
                                    }
                                }
                            }
                        }
                        departmentList.setDepartmentList(beanList);
                        departmentList.setNum(infoBean.getData().getCheck().size());
                        DepartmentFileutil.SaveDepartment(departmentList);
                        objectBoxHelper.RxAddList(deviceListBean);
//                    try {
//                        Log.d(TAG,"发送:"+new Gson().toJson(txBean));
//                        send(out, DesCBCUtil.encryptDES(new Gson().toJson(txBean).getBytes("UTF-8"), "key_123_"));
////                        send(out, new Gson().toJson(txBean).getBytes("GBK"));
//                    } catch (UnsupportedEncodingException e) {
//                        e.printStackTrace();
//                    } catch (Exception e) {
//                        e.printStackTrace();
//                    }
                    }
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    private void close(OutputStream out) {
        if (out != null) {
            try {
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private void close(InputStream in) {
        if (in != null) {
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private void close(Socket socket) {
        if (socket != null) {
            try {
                socket.close();
            } catch (IOException e) {
                Log.e(TAG, "run: ", e);
            }
        }
    }
    public interface Callback {
        void callbcak(String msg);
    }
    public static String toUtf8(String str) {
        String result = null;
        try {
            result = new String(str.getBytes("UTF-8"), "UTF-8");
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return result;
    }

    public static byte[] byteMerger(byte[] bt1, byte[] bt2){
        byte[] bt3 = new byte[bt1.length+bt2.length];
        System.arraycopy(bt1, 0, bt3, 0, bt1.length);
        System.arraycopy(bt2, 0, bt3, bt1.length, bt2.length);
        return bt3;
    }

    /**
     * 更新盘点数据到客户端
     */
    private Observable upCheckdata(ObjectBoxHelper objectBoxHelper,OutputStream os){
        return Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> e) throws Exception {
              List<DeviceEntity>entities =  objectBoxHelper.Query("user", DeviceEntity_.username);
              if (entities.size()>0) {
                  TxBean txBean = new TxBean();
                  txBean.setLimit(10);
                  txBean.setPage(1);
                  txBean.setURL("/dev/deviceInfo/deviceCheckUpdate");
                  List<TxBean.DeviceCheckListBean> deviceCheckListBean = new LinkedList<>();
                  for (int i = 0; i < entities.size(); i++) {
                      TxBean.DeviceCheckListBean deviceCheckListBean1 = new TxBean.DeviceCheckListBean();
                      deviceCheckListBean1.setUseDepartmentCode(entities.get(i).getUseDepartmentCode());
                      deviceCheckListBean1.setDeviceRealName(entities.get(i).getDeviceName());
                      deviceCheckListBean1.setDeviceStreamCode(entities.get(i).getDeviceStreamCode());
                      deviceCheckListBean1.setLocationFloor(entities.get(i).getLocationFloor());
                      deviceCheckListBean1.setLocationIbm(entities.get(i).getLocationIbm());
                      deviceCheckListBean1.setLocationPosition(entities.get(i).getLocationPosition());
                      deviceCheckListBean1.setLocationRoom(entities.get(i).getLocationRoom());
                      deviceCheckListBean1.setUseDepartment(entities.get(i).getUseDepartment());
                      deviceCheckListBean.add(deviceCheckListBean1);
                  }
                  txBean.setDeviceCheckList(deviceCheckListBean);
                  Log.d(TAG,"发送数据"+new Gson().toJson(txBean));
                  send(os, DesCBCUtil.encryptDES(new Gson().toJson(txBean).getBytes("UTF-8"),"key_123_"));
                  e.onNext("succes");
              }
            }
        }).subscribeOn(Schedulers.newThread())
                .observeOn(Schedulers.trampoline());
    }

    /**
     * 更新出库数据到客户端
     */
    private Observable upBoxdata(ObjectBoxHelper objectBoxHelper,OutputStream os){
        return Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> e) throws Exception {
                List<DeviceEntity>entities =  objectBoxHelper.Query("qrcode", DeviceEntity_.username);
                if (entities.size()>0) {
                    DeviceUpBean deviceUpBean = new  DeviceUpBean();
                    deviceUpBean.setURL("/dev/deviceInfo/updateDeviceInfo/list");
                    List<DeviceUpBean.DeviceInfoListBean> deviceListBean = new LinkedList<>();
                    for (int i = 0; i < entities.size(); i++) {
                        objectBoxHelper.remove(entities.get(i).getId());
                        DeviceUpBean.DeviceInfoListBean deviceInfoListBean = new DeviceUpBean.DeviceInfoListBean();
                        deviceInfoListBean.setId(entities.get(i).getDeviceStreamCode());
                        deviceInfoListBean.setStatus(0);
                        deviceListBean.add(deviceInfoListBean);
                    }
                    deviceUpBean.setDeviceInfoList(deviceListBean);
                    Log.d(TAG,"发送数据"+new Gson().toJson(deviceUpBean));
                    send(os, DesCBCUtil.encryptDES(new Gson().toJson(deviceUpBean).getBytes("UTF-8"),"key_123_"));
                    e.onNext("succes");
                }
            }
        }).subscribeOn(Schedulers.newThread())
                .observeOn(Schedulers.trampoline());
    }
}
